#ifndef KINECT_GUI_H
#define KINECT_GUI_H

#include <QMainWindow>
#include <QFileDialog>
#include <QMessageBox>
#include <QTimer>
#include <XnOpenNI.h>
#include <XnLog.h>
#include <XnCppWrapper.h>
#include <QDebug>
//#include <opencv2/core/core.hpp>
//#include <opencv2/highgui/highgui.hpp>
//#include <cv.h>
//#include <cvaux.h>
#include <QVTKWidget.h>
#include <pcl/io/pcd_io.h>
#include <pcl/common/common.h>


namespace Ui {
class KINECT_GUI;
}

class KINECT_GUI : public QMainWindow
{
    Q_OBJECT

public:
    explicit KINECT_GUI(QWidget *parent = 0);
    ~KINECT_GUI();
    void callback_called(QString msg);

private:
    Ui::KINECT_GUI *ui;
    //------------------------------------------- ---
    //OPENNI Kinect Stuff
    //----------------------------------------------
    // Context and Status
    xn::Context context;        bool context_init;
    XnStatus nRetVal; // Statuframes cheker
    QString filename; // Filename of the Recorded Session
    xn::Player Player;
    //Generators
    xn::DepthGenerator depth;   bool depth_init;
    xn::ImageGenerator color;   bool color_init;
    xn::UserGenerator user;     bool user_init;
    bool user_cloud_populated;
    // Data types
    xn::DepthMetaData depthMD;  //Deth Meta data
    xn::ImageMetaData imageMD;  //Image Meta Data
    xn::SceneMetaData sceneMD;  //Scene meta data - It will be used to segment the USER
    const XnRGB24Pixel* pImageMap;    //Pointer to color map
    //cv::Mat  rgb_image;                // for OPENCV IMAGE
    const XnDepthPixel* pDepthMap;    //Pointer to Depth map
    const XnLabel* pLabel; //pointer for identifying users
    unsigned int n_pixels; // number of pixels in depth map
    XnPoint3D* proj; // 3D points in projective space
    XnPoint3D* wrld; // 3D points in euclidean space
    // Number of Frames for Recording
    unsigned int n_frames;
    XnSkeletonJointPosition
                            HEAD           ,
                            NECK           ,
                            TORSO          ,
                            WAIST          ,
                            LEFT_COLLAR    ,
                            LEFT_SHOULDER  ,
                            LEFT_ELBOW     ,
                            LEFT_WRIST     ,
                            LEFT_HAND      ,
                            LEFT_FINGERTIP ,
                            RIGHT_COLLAR   ,
                            RIGHT_SHOULDER ,
                            RIGHT_ELBOW    ,
                            RIGHT_WRIST    ,
                            RIGHT_HAND     ,
                            RIGHT_FINGERTIP,
                            LEFT_HIP       ,
                            LEFT_KNEE      ,
                            LEFT_ANKLE     ,
                            LEFT_FOOT      ,
                            RIGHT_HIP      ,
                            RIGHT_KNEE     ,
                            RIGHT_ANKLE    ,
                            RIGHT_FOOT     ;

    bool user_1_skeleton_available; // User 1 skeleton available


    //calibration parameters of kinect depth camera.
    //source: http://nicolas.burrus.name/index.php/Research/KinectCalibration.
    double depthm,cx_d,cy_d,fx,fy;
    //CvMat* depthMetersMat ;
    bool pose_needed; // boolean is TRUE if pose is needed for skeleton detection
    //Callbacks
    XnCallbackHandle
    hUserCallbacks,
    hCalibrationStart,
    hCalibrationComplete,
    hPoseDetected,
    hCalibrationInProgress,
    //    else
    hPoseInProgress;

    //callback for new user
    static void XN_CALLBACK_TYPE User_NewUser(xn::UserGenerator& generator, XnUserID nId, void* pCookie);
    //callback for User Lost3
    static void XN_CALLBACK_TYPE User_LostUser(xn::UserGenerator& generator, XnUserID nId, void* pCookie);
    //callback for calibration started
    static void XN_CALLBACK_TYPE User_Calibration_Start(xn::SkeletonCapability& capability, XnUserID nId, void* pCookie);

    //callback for calibration Completed
    static void XN_CALLBACK_TYPE User_Calibration_Complete(xn::SkeletonCapability& capability, XnUserID nId, XnCalibrationStatus calibrationError, void* pCookie);

private slots:
    void on_action_Open_triggered();
    void on_bt_startVideo_clicked();
    void process_frame();
    //void convert_to_opencv( xn::ImageMetaData *imgMD,const XnRGB24Pixel* pimgmap, cv::Mat * opcv);
    void convert_to_world(XnPoint3D* projection , XnPoint3D* world , const  XnDepthPixel*  depthpxl);
    void convert_to_PCL (XnPoint3D* world ,  const XnRGB24Pixel* pimgmap , const XnLabel* pLbl , unsigned int usert_id);
    void draw_limbs(XnSkeletonJointPosition * j1 , XnSkeletonJointPosition *j2, QString name);
};

#endif // KINECT_GUI_H
